package com.action.mvc.auth.controller;

import com.action.mvc.auth.common.AjaxResult;
import com.action.mvc.auth.common.Whether;
import com.action.mvc.auth.context.LoginUserCache;
import com.action.mvc.auth.context.NativeCache;
import com.action.mvc.auth.context.UserContext;
import com.action.mvc.auth.dto.Accordion;
import com.action.mvc.auth.entity.*;
import com.action.mvc.auth.service.RoleService;
import com.action.mvc.auth.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.*;

/**
 * Created by Wuxiang on 2017/4/24.
 *
 * http://localhost:8080/login?name=aaa&password=123
 */
@Controller
public class LoginController {
    @Autowired
    private UserService userService;
    @Autowired
    private NativeCache nativeCache;
    @Autowired
    private RoleService roleService;

    @RequestMapping(value = "/auth",method = RequestMethod.GET)
    public String index() {
        if(null != UserContext.getCurrent() && null !=UserContext.getCurrent().getUser()){
            return "main";
        }
        return "login";
    }

    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String login(Model model,String name,String password) {
        User user = userService.getUser(name, password);
        if (user == null) {
            model.addAttribute("msg", AjaxResult.error("用户尚未注册！登陆失败。"));
            return "login";
        }

        try {
            LoginUserCache.put(user);   //半小时过期

            if (Objects.equals("admin", user.getName())) {
                model.addAttribute("accordions",getAccordion(true,null));
            }else {
                List<UserRole> userRoles = userService.getUserRoleByUserId(user.getId());
                if (userRoles == null || userRoles.size() == 0) {
                    model.addAttribute("msg", AjaxResult.error("用户没有被授权！"));
                    return "login";
                }

                List<Long> roleIds = new ArrayList<>();
                userRoles.forEach(userRole -> {
                    roleIds.add(userRole.getId());
                });

                List<Role> roles = roleService.getRoles(roleIds);
                nativeCache.setRoles(user.getId(), roles);

                LoginUserCache.put(user);
                List<Accordion> accordions = getAccordion(false,user.getId());
                model.addAttribute("accordions",accordions);
                LoginUserCache.setAccorions(user.getName(), accordions);
            }
            return "main";
        } catch (Exception e) {
            e.printStackTrace();
            LoginUserCache.remove(user.getName());
            model.addAttribute("msg", AjaxResult.error("异常！！！"));
            return "login";
        }
    }

    private List<Accordion> getAccordion(boolean isAdmin , Long userId)
    {
        Set<String> permissionUrls = new HashSet<>();
        Set<Long>rootFunctionIdSet = new HashSet<>();
        if(!isAdmin){
            for(Role role:nativeCache.getRoles(userId)){
                List<RoleFunction>roleFunction = roleService.getRoleFunctions(role.getId());
                for(RoleFunction rf : roleFunction){
                    Function func = nativeCache.getFunction(rf.getFunctionId());
                    if(Whether.YES.getValue() ==func.getAccordion() ){
                        rootFunctionIdSet.add(func.getId());
                    }else{
                        permissionUrls.add(func.getUrl());
                    }
                }
            }
        }

        Map<Long,Accordion> accordionMap = new HashMap<>();
        List<Accordion> permissionAccordionSet = new LinkedList<>();

        List<Function> functions = nativeCache.getFunctions();

        List<Accordion> rootAccordionSet = new LinkedList<>();

        for(Function function:functions){
            Accordion accordion = new Accordion(function.getId(),function.getParentId(),function.getName(),function.getUrl(),function.getSerialNum());
            accordionMap.put(function.getId(), accordion);
            if(!isAdmin){
                if(permissionUrls.contains(function.getUrl())){
                    permissionAccordionSet.add(accordion);
                }
                if(rootFunctionIdSet.contains(function.getUrl())){
                    rootAccordionSet.add(accordion);
                }
            }else{
                permissionAccordionSet.add(accordion);
                if(Whether.YES.getValue() == function.getAccordion()){
                    rootAccordionSet.add(accordion);
                }
            }
        }

        Collections.sort(rootAccordionSet);
        Collections.sort(permissionAccordionSet);

        for(Accordion accordion : rootAccordionSet){
            completeAccordion(permissionAccordionSet,accordion);
        }
        return rootAccordionSet;
    }

    private void completeAccordion(List<Accordion> permissionAccordionSet,
                                   Accordion rootAccordion) {
        for(Accordion accordion : permissionAccordionSet){
            if(accordion.getParentId() == rootAccordion.getId()){
                rootAccordion.getChildren().add(accordion);
            }
        }

    }

    @RequestMapping(value = "/logout",method = RequestMethod.GET)
    public String logout(){
        if(null != UserContext.getCurrent() && null !=UserContext.getCurrent().getUser()){
            LoginUserCache.remove(UserContext.getCurrent().getUser().getName());
        }
        return "login";
    }
}
